import type React from 'react';
import { useCallback, useMemo, useState } from 'react';
import { Matrix2D } from '../../Matrix2D';
import { TransformUtils } from '../../transformUtils';
import {
  type Point2D,
  type Transform2D,
  TransformType,
  type Vector2D,
} from '../../types';
import {
  MatrixCanvas,
  MatrixInfo,
  TransformControls,
  TransformHistory,
} from '..';
import styles from './MatrixTransform.module.less';

interface MatrixTransformProps {
  initialPoints?: Point2D[];
  initialVectors?: Vector2D[];
  width?: number;
  height?: number;
  showControls?: boolean;
  showMatrix?: boolean;
  showHistory?: boolean;
}

/**
 * 矩阵变换可视化组件
 */
export const MatrixTransform: React.FC<MatrixTransformProps> = ({
  initialPoints = [],
  initialVectors = [],
  width = 800,
  height = 600,
  showControls = true,
  showMatrix = true,
  showHistory = true,
}) => {
  const [matrix, setMatrix] = useState<Matrix2D>(new Matrix2D());
  const [points, setPoints] = useState<Point2D[]>(initialPoints);
  const [vectors, setVectors] = useState<Vector2D[]>(initialVectors);
  const [transformOrigin, setTransformOrigin] = useState<Point2D>({
    x: 0,
    y: 0,
  });
  const [selectedTransform, setSelectedTransform] = useState<TransformType>(
    TransformType.TRANSLATE,
  );

  // 变换后的点
  const transformedPoints = useMemo(
    () => matrix.transformPoints(points),
    [matrix, points],
  );

  // 变换后的向量
  const transformedVectors = useMemo(
    () => matrix.transformVectors(vectors),
    [matrix, vectors],
  );

  // 变换原点
  const originPoint = useMemo(
    () => matrix.transformPoint(transformOrigin),
    [matrix, transformOrigin],
  );

  // 变换操作
  const handleTranslate = useCallback(
    (tx: number, ty: number) => {
      const newMatrix = matrix.clone();
      newMatrix.translate(tx, ty, { origin: transformOrigin });
      setMatrix(newMatrix);
    },
    [matrix, transformOrigin],
  );

  // 注意：由于y轴方向已改为向上，正角度表示顺时针旋转
  const handleRotate = useCallback(
    (angle: number) => {
      const newMatrix = matrix.clone();
      newMatrix.rotateDegrees(angle, {
        origin: transformOrigin,
      });
      setMatrix(newMatrix);
    },
    [matrix, transformOrigin],
  );

  const handleScale = useCallback(
    (sx: number, sy: number) => {
      const newMatrix = matrix.clone();
      newMatrix.scale(sx, sy, {
        origin: transformOrigin,
        sx: 0,
        sy: 0,
      });
      setMatrix(newMatrix);
    },
    [matrix, transformOrigin],
  );

  const handleShear = useCallback(
    (shx: number, shy: number) => {
      const newMatrix = matrix.clone();
      newMatrix.shear(shx, shy, {
        origin: transformOrigin,
        shx: 0,
        shy: 0,
      });
      setMatrix(newMatrix);
    },
    [matrix, transformOrigin],
  );

  const handleReset = useCallback(() => {
    setMatrix(new Matrix2D());
  }, []);

  const handleUndo = useCallback(() => {
    const newMatrix = matrix.clone();
    if (newMatrix.undo()) {
      setMatrix(newMatrix);
    }
  }, [matrix]);

  const handleAddPoint = useCallback((x: number, y: number) => {
    setPoints((prev) => [...prev, { x, y }]);
  }, []);

  const handleAddVector = useCallback((x: number, y: number) => {
    setVectors((prev) => [...prev, { x, y }]);
  }, []);

  const handleClearPoints = useCallback(() => {
    setPoints([]);
  }, []);

  const handleClearVectors = useCallback(() => {
    setVectors([]);
  }, []);

  const handleSetTransformOrigin = useCallback((x: number, y: number) => {
    setTransformOrigin({ x, y });
  }, []);

  // 创建测试数据
  const handleCreateTestData = useCallback(() => {
    const testPoints = TransformUtils.createTestPoints(5, { x: 200, y: 200 });
    const testVectors = TransformUtils.createTestVectors(3, 50);
    setPoints(testPoints);
    setVectors(testVectors);
  }, []);

  return (
    <div className={styles.container}>
      <div className={styles.grid}>
        {/* 画布区域 */}
        <div className={styles.canvasSection}>
          <MatrixCanvas
            width={width}
            height={height}
            points={points}
            vectors={vectors}
            transformedPoints={transformedPoints}
            transformedVectors={transformedVectors}
            transformOrigin={transformOrigin}
            transformedOrigin={originPoint}
            onAddPoint={handleAddPoint}
            onSetTransformOrigin={handleSetTransformOrigin}
          />
        </div>

        {/* 控制面板 */}
        {showControls && (
          <div className={styles.controlSection}>
            <TransformControls
              selectedTransform={selectedTransform}
              onTransformChange={setSelectedTransform}
              onTranslate={handleTranslate}
              onRotate={handleRotate}
              onScale={handleScale}
              onShear={handleShear}
              onReset={handleReset}
              onUndo={handleUndo}
              onAddPoint={handleAddPoint}
              onAddVector={handleAddVector}
              onClearPoints={handleClearPoints}
              onClearVectors={handleClearVectors}
              onCreateTestData={handleCreateTestData}
            />
          </div>
        )}

        {/* 矩阵信息 */}
        {showMatrix && (
          <div className={styles.matrixSection}>
            <MatrixInfo
              matrix={matrix.getMatrix()}
              cssTransform={matrix.toCSSTransform()}
            />
          </div>
        )}

        {/* 变换历史 */}
        {showHistory && (
          <div className={styles.historySection}>
            <TransformHistory history={matrix.getHistory()} />
          </div>
        )}
      </div>
    </div>
  );
};
